-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Replace jQuery tab visibility with Vue reactivity (Fixes #4700) #4701
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Moved expert mode state to reactive Vue model for declarative UI updates - Replaced imperative jQuery .toggle() calls with Vue v-show directives in template - Simplified updateTabList to only sync checkbox state with Vue model
WalkthroughThe changes replace jQuery-based tab visibility logic with Vue reactive state management. An Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Checkbox as Expert Mode Checkbox
participant Vue as Vue Reactivity
participant DOM as Template (v-show)
rect rgb(200, 220, 240)
Note over User,DOM: Old Approach (jQuery-based)
User->>Checkbox: Click to toggle
Checkbox->>updateTabList: jQuery event handler
updateTabList->>DOM: Directly toggle visibility
end
rect rgb(240, 200, 220)
Note over User,DOM: New Approach (Vue-based)
User->>Checkbox: Click to toggle
Checkbox->>Vue: v-model updates expertMode
Vue->>DOM: v-show re-evaluates based on expertMode
DOM-->>User: Tabs show/hide reactively
end
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
|
Preview URL: https://pr4701.betaflight-app-preview.pages.dev |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/index.html (2)
149-149: Simplify feature flag checks with optional chaining.The pattern
FC.FEATURE_CONFIG?.features?.isEnabled && FC.FEATURE_CONFIG.features.isEnabled('X')can be simplified using optional chaining on the method call itself.Apply this diff to simplify the feature checks:
- <li class="tab_osd" v-show="FC.FEATURE_CONFIG?.features?.isEnabled && FC.FEATURE_CONFIG.features.isEnabled('OSD')"><a href="#" i18n="tabOsd" class="tabicon ic_osd" i18n_title="tabOsd"></a></li> + <li class="tab_osd" v-show="FC.FEATURE_CONFIG?.features?.isEnabled?.('OSD')"><a href="#" i18n="tabOsd" class="tabicon ic_osd" i18n_title="tabOsd"></a></li>- <li class="tab_transponder" v-show="FC.FEATURE_CONFIG?.features?.isEnabled && FC.FEATURE_CONFIG.features.isEnabled('TRANSPONDER')"><a href="#" i18n="tabTransponder" class="tabicon ic_transponder" i18n_title="tabTransponder"></a></li> + <li class="tab_transponder" v-show="FC.FEATURE_CONFIG?.features?.isEnabled?.('TRANSPONDER')"><a href="#" i18n="tabTransponder" class="tabicon ic_transponder" i18n_title="tabTransponder"></a></li>- <li class="tab_led_strip" v-show="FC.FEATURE_CONFIG?.features?.isEnabled && FC.FEATURE_CONFIG.features.isEnabled('LED_STRIP')"><a href="#" i18n="tabLedStrip" class="tabicon ic_led" i18n_title="tabLedStrip"></a></li> + <li class="tab_led_strip" v-show="FC.FEATURE_CONFIG?.features?.isEnabled?.('LED_STRIP')"><a href="#" i18n="tabLedStrip" class="tabicon ic_led" i18n_title="tabLedStrip"></a></li>Also applies to: 151-151, 152-152
146-147: Considerv-ifinstead ofv-showfor build-option tabs.Build options don't change at runtime (they're determined by firmware compilation), so using
v-ifwould remove these tabs from the DOM entirely when not applicable, reducing memory footprint. Thev-showdirective is better suited for frequently toggled elements like expert mode tabs.Apply this diff if you prefer conditional rendering for build-option tabs:
- <li class="tab_servos" v-show="['USE_SERVOS','USE_WING'].some(opt => FC.CONFIG?.buildOptions?.includes(opt))"><a href="#" i18n="tabServos" class="tabicon ic_servo" i18n_title="tabServos"></a></li> - <li class="tab_gps" v-show="FC.CONFIG?.buildOptions?.includes('USE_GPS')"><a href="#" i18n="tabGPS" class="tabicon ic_gps" i18n_title="tabGPS"></a></li> + <li class="tab_servos" v-if="['USE_SERVOS','USE_WING'].some(opt => FC.CONFIG?.buildOptions?.includes(opt))"><a href="#" i18n="tabServos" class="tabicon ic_servo" i18n_title="tabServos"></a></li> + <li class="tab_gps" v-if="FC.CONFIG?.buildOptions?.includes('USE_GPS')"><a href="#" i18n="tabGPS" class="tabicon ic_gps" i18n_title="tabGPS"></a></li>
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/components/init.js(1 hunks)src/index.html(2 hunks)src/js/utils/updateTabList.js(1 hunks)
🧰 Additional context used
🧠 Learnings (9)
📓 Common learnings
Learnt from: haslinghuis
Repo: betaflight/betaflight-configurator PR: 4510
File: src/js/msp.js:384-391
Timestamp: 2025-09-19T20:42:20.332Z
Learning: Complex MSP duplicate handling fixes in Betaflight Configurator can cause infinite loading messages when changing tabs due to disruption of the callback resolution mechanism. Simple code-only duplicate detection (using this.callbacks.some((instance) => instance.code === code)) is the safer approach that preserves tab switching functionality.
Learnt from: haslinghuis
Repo: betaflight/betaflight-configurator PR: 4597
File: src/js/utils/common.js:95-127
Timestamp: 2025-09-09T20:02:33.475Z
Learning: In the Betaflight Configurator codebase, the Chromium v140 compatibility issue with sortSelect was resolved by rewriting the implementation to use native DOM APIs (Array.from, select.options, select.remove, select.add) instead of jQuery DOM manipulation methods (this.children, this.empty().append). The fix still performs DOM operations but avoids the specific jQuery methods that were causing issues in Chromium v140.
Learnt from: haslinghuis
Repo: betaflight/betaflight-configurator PR: 4577
File: src/js/tabs/configuration.js:580-590
Timestamp: 2025-08-22T22:43:45.415Z
Learning: In src/js/tabs/configuration.js, hiding the entire .mag_align_box for API versions < 1.47 is intentional behavior because these MAG alignment options were not present or have changed significantly between API versions. The code has been reorganized for better maintenance.
Learnt from: haslinghuis
Repo: betaflight/betaflight-configurator PR: 4569
File: src/js/tabs/receiver.js:957-960
Timestamp: 2025-08-13T15:13:10.214Z
Learning: In src/js/tabs/receiver.js, the updateInterpolationView() function already contains logic to hide ".rcSmoothing-feedforward-cutoff" when FC.RX_CONFIG.rcSmoothingFeedforwardCutoff === 0, which handles the API ≥ 1.47 case since feedforward cutoff isn't initialized from DOM for newer APIs.
Learnt from: mituritsyn
Repo: betaflight/betaflight-configurator PR: 4526
File: src/js/gui.js:43-43
Timestamp: 2025-06-20T12:35:49.283Z
Learning: In the Betaflight Configurator codebase, tabs in `defaultCloudBuildTabOptions` are conditionally displayed based on firmware build options. The logic in `serial_backend.js` checks `FC.CONFIG.buildOptions` and only adds tabs to `GUI.allowedTabs` if the firmware was built with support for that feature.
Learnt from: haslinghuis
Repo: betaflight/betaflight-configurator PR: 4569
File: src/js/tabs/receiver.js:650-674
Timestamp: 2025-08-13T15:12:48.509Z
Learning: In src/js/tabs/receiver.js, the rcSmoothing-feedforward-cutoff element is a child of rcSmoothing-feedforward-manual in the DOM structure, so hiding the parent automatically hides the child.
📚 Learning: 2025-08-22T22:43:45.415Z
Learnt from: haslinghuis
Repo: betaflight/betaflight-configurator PR: 4577
File: src/js/tabs/configuration.js:580-590
Timestamp: 2025-08-22T22:43:45.415Z
Learning: In src/js/tabs/configuration.js, hiding the entire .mag_align_box for API versions < 1.47 is intentional behavior because these MAG alignment options were not present or have changed significantly between API versions. The code has been reorganized for better maintenance.
Applied to files:
src/js/utils/updateTabList.jssrc/index.html
📚 Learning: 2025-08-13T15:13:10.214Z
Learnt from: haslinghuis
Repo: betaflight/betaflight-configurator PR: 4569
File: src/js/tabs/receiver.js:957-960
Timestamp: 2025-08-13T15:13:10.214Z
Learning: In src/js/tabs/receiver.js, the updateInterpolationView() function already contains logic to hide ".rcSmoothing-feedforward-cutoff" when FC.RX_CONFIG.rcSmoothingFeedforwardCutoff === 0, which handles the API ≥ 1.47 case since feedforward cutoff isn't initialized from DOM for newer APIs.
Applied to files:
src/js/utils/updateTabList.js
📚 Learning: 2025-06-20T12:35:49.283Z
Learnt from: mituritsyn
Repo: betaflight/betaflight-configurator PR: 4526
File: src/js/gui.js:43-43
Timestamp: 2025-06-20T12:35:49.283Z
Learning: In the Betaflight Configurator codebase, tabs in `defaultCloudBuildTabOptions` are conditionally displayed based on firmware build options. The logic in `serial_backend.js` checks `FC.CONFIG.buildOptions` and only adds tabs to `GUI.allowedTabs` if the firmware was built with support for that feature.
Applied to files:
src/js/utils/updateTabList.jssrc/index.html
📚 Learning: 2025-09-02T07:45:48.606Z
Learnt from: blckmn
Repo: betaflight/betaflight-configurator PR: 4583
File: src/js/tabs/firmware_flasher.js:949-961
Timestamp: 2025-09-02T07:45:48.606Z
Learning: In src/js/tabs/firmware_flasher.js, the config file loading code path after firmware loading (in the load_file click handler) cannot be reached when UF2 firmware is loaded, according to the maintainer blckmn. This code is maintained for backward compatibility with unified target settings and will be refactored in a future PR.
Applied to files:
src/js/utils/updateTabList.js
📚 Learning: 2025-06-27T22:06:49.210Z
Learnt from: haslinghuis
Repo: betaflight/betaflight-configurator PR: 4532
File: src/js/VirtualFC.js:234-234
Timestamp: 2025-06-27T22:06:49.210Z
Learning: In the betaflight-configurator codebase, the VirtualFC.js AUX_CONFIG array must stay synchronized with the betaflight firmware's msp_box.c definitions to ensure proper auxiliary mode functionality. Changes to mode names should follow the firmware source code even if it potentially breaks backward compatibility with saved presets.
Applied to files:
src/components/init.jssrc/index.html
📚 Learning: 2025-09-10T18:26:10.136Z
Learnt from: haslinghuis
Repo: betaflight/betaflight-configurator PR: 4601
File: package.json:125-125
Timestamp: 2025-09-10T18:26:10.136Z
Learning: In betaflight-configurator, dependency updates are handled incrementally - Vue dependencies are updated separately from Vite dependencies for better isolation and maintainability.
Applied to files:
src/components/init.js
📚 Learning: 2025-09-19T20:42:20.332Z
Learnt from: haslinghuis
Repo: betaflight/betaflight-configurator PR: 4510
File: src/js/msp.js:384-391
Timestamp: 2025-09-19T20:42:20.332Z
Learning: Complex MSP duplicate handling fixes in Betaflight Configurator can cause infinite loading messages when changing tabs due to disruption of the callback resolution mechanism. Simple code-only duplicate detection (using this.callbacks.some((instance) => instance.code === code)) is the safer approach that preserves tab switching functionality.
Applied to files:
src/index.html
📚 Learning: 2025-09-15T15:19:47.087Z
Learnt from: haslinghuis
Repo: betaflight/betaflight-configurator PR: 4611
File: src/tabs/configuration.html:247-249
Timestamp: 2025-09-15T15:19:47.087Z
Learning: In the Betaflight Configurator's configuration.html, duplicate "not found" elements using the same i18n key (like configurationSensorGyroToUseNotFound) may be intentionally placed in different UI sections that are conditionally displayed based on firmware version. The old gyro alignment section (.gyro_alignment_inputs_notfound) is used for older firmware, while the new gyro enable section (.gyro_notfound) is used for firmware 1.47+.
Applied to files:
src/index.html
🔇 Additional comments (3)
src/components/init.js (1)
41-42: LGTM! Clean addition of reactive expert mode flag.The
expertModeproperty is properly initialized and will be reactive within the Vue model, enabling the template-driven tab visibility changes.src/index.html (2)
91-91: LGTM! Proper two-way binding for expert mode.The
v-model="expertMode"binding correctly synchronizes the checkbox with the Vue reactive state, enabling instant updates to tab visibility.
140-140: LGTM! Expert mode tabs properly controlled by reactive state.These tabs correctly use
v-show="expertMode"for instant visibility toggling when the expert mode checkbox changes.Also applies to: 145-145, 153-154
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is something that I've been playing with locally, along with loading the tabs themselves with Vue directly. I don't have much time to work on the more complex behind-the-scenes stuff nowadays, I'm thankful that there's effort going into this still 👍
|
Going forward this would be a great way to gate the tab content itself, but this is a great step forward already |
haslinghuis
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you. We should use Vue more - but occupied working on serial backend never get to it.



Replace jQuery tab toggles with Vue reactivity (Fixes #4700)
Overview
Moves tab visibility logic from jQuery to Vue so Expert Mode and feature-based tabs update instantly and stay in sync without DOM flicker.
What changed
expertModeto the Vue model and bound the checkbox withv-model.v-showfor visibility:features.isEnabled(...).toggle()calls in updateTabList.js; it now just syncs the checkbox to Vue state.Why
Test
Fixes #4700
Summary by CodeRabbit
New Features
Changes